﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EuroManager.Domain.Simulator.Engine;
using EuroManager.Domain.Simulator.Engine.Movements;
using EuroManager.Domain.Simulator.Helpers;
using NUnit.Framework;

namespace EuroManager.Domain.Simulator.Tests.Engine.Movements
{
    [TestFixture]
    public class ArriveMovementTests
    {
        [Test]
        public void ShouldNotMoveWhenStandingAtTargetLocation()
        {
            Vector2D location = new Vector2D(15, 8);

            ArriveMovement movement = new ArriveMovement(location, Vector2D.Zero, location, 1, 1, 3, 0, 0);
            movement.Update(0.2f);

            Assert.AreEqual(location, movement.Location);
        }

        [Test]
        public void ShouldNotFinishAtStart()
        {
            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-1, 2), new Vector2D(12, -27), 1, 1, 3, 0.1f, 0);

            Assert.IsFalse(movement.IsFinished);
        }

        [Test]
        public void ShouldFinishEventually()
        {
            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-1, 2), new Vector2D(12, -27), 1, 1, 3, 0.1f, 0);
            TestHelper.Advance(100, movement);

            Assert.IsTrue(movement.IsFinished);
        }

        [Test]
        public void ShouldReachDestinationEventually()
        {
            Vector2D destination = new Vector2D(12, -27);
            float tolerance = 0.5f;

            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-1, 2), destination, 1, 1, 3, tolerance, 0);
            TestHelper.Advance(100, movement);

            Assert.IsTrue(Vector2D.Equals(destination, movement.Location, tolerance));
        }

        [Test]
        public void ShouldReachDestinationWithHighSpeed()
        {
            Vector2D destination = new Vector2D(12, -27);
            float tolerance = 0.5f;
            
            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-10, 20), destination, 100, 50, 200, tolerance, 0);
            TestHelper.Advance(10, movement);

            Assert.IsTrue(Vector2D.Equals(destination, movement.Location, tolerance));
        }

        [Test]
        public void ShouldNotReachDestinationLongBeforeTime()
        {
            Vector2D destination = new Vector2D(12, -27);
            float tolerance = 0.1f;
            float time = 30;

            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-10, 20), destination, 3, 2, 7, tolerance, time);
            TestHelper.Advance(0.8f * time, movement);

            Assert.IsFalse(Vector2D.Equals(destination, movement.Location, tolerance));
        }

        [Test]
        public void ShouldReachDestinationOnTime()
        {
            Vector2D destination = new Vector2D(12, -27);
            float tolerance = 0.1f;
            float time = 30;

            ArriveMovement movement = new ArriveMovement(new Vector2D(3, 5), new Vector2D(-10, 20), destination, 3, 2, 7, tolerance, time);
            TestHelper.Advance(time, movement);

            Assert.IsTrue(Vector2D.Equals(destination, movement.Location, tolerance));
        }
    }
}
